from enum import Enum, StrEnum
import logging
from typing import Optional
from sqlalchemy import func
from sqlalchemy.orm import Mapped, mapped_column
from models.engine import db
from models.types import StringUUID

class RobFuncType(Enum):
    AGENT = 1
    FUNCTION = 2
    INTERFACE = 3

    @staticmethod
    def get_zh_str(val:int)->str:
        return {
            RobFuncType.AGENT.value: "智能体",
            RobFuncType.FUNCTION.value: "系统函数",
            RobFuncType.INTERFACE.value: "外部接口",
        }.get(val, "")
    
    @staticmethod
    def get_code(val:int)->str:
        return {
            RobFuncType.AGENT.value: "agent",
            RobFuncType.FUNCTION.value: "function",
            RobFuncType.INTERFACE.value: "interface",
        }.get(val, "")
    
    @staticmethod
    def from_code(val:str)->Optional['RobFuncType']:
        if val in RobFuncType.get_codes():
            return {
                "agent": RobFuncType.AGENT,
                "function": RobFuncType.FUNCTION,
                "interface": RobFuncType.INTERFACE,
            }.get(val, None)
        return None
    
    @staticmethod
    def get_codes()->list[str]:
        return ["agent", "function", "interface"]

class RobIntRecTermStatus(StrEnum):
    PENDING = 'p'
    INDEXING = 'i'
    DONE = 'd'
    FAILED = 'f'
    DELETED = 'e'
    FOUND_SAME='s'

    @staticmethod
    def get_zh_str(val:str)->str:
        return {
            RobIntRecTermStatus.PENDING.value: "待索引",
            RobIntRecTermStatus.INDEXING.value: "索引中",
            RobIntRecTermStatus.DONE.value: "完成",
            RobIntRecTermStatus.FAILED.value: "失败",
            RobIntRecTermStatus.DELETED.value: "已删除",
            RobIntRecTermStatus.FOUND_SAME.value: "已存在",
        }.get(val, "未知")

class IntentRecoTerms(db.Model):
    __tablename__ = "int_rec_terms"
    __table_args__ = (db.PrimaryKeyConstraint("id", name="int_rec_terms_pkey"),
                      db.Index("int_rec_terms_intent_cmd_idx", "cmd_id"))
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True,server_default=db.text("nextval('int_rec_terms_id_seq'::regclass)"))
    tenant_id = db.Column(StringUUID, nullable=False,comment="租户ID")
    cmd_id = db.Column(StringUUID, nullable=False,comment="命令ID")
    term = db.Column(db.String(255), nullable=False,comment="识别词")
    hit_count = db.Column(db.Integer, nullable=False,default=0,comment="命中次数")
    status = db.Column(db.String(1), nullable=False,default="p",comment="状态")
    segment_id = db.Column(StringUUID, nullable=True,comment="分词ID")
    same_content = db.Column(db.String(512), nullable=True,comment="同义词内容")
    created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp(),comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False,comment="创建人")
    @property
    def status_zh_str(self) -> str:
        return RobIntRecTermStatus.get_zh_str(self.status)

class RobFuncs(db.Model):
    __tablename__ = "rob_funcs"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="rob_funcs_pkey"),
    )
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),comment="如果是agent，则是系统agentID。")
    
    tenant_id = db.Column(StringUUID, nullable=False)
    name = db.Column(db.String(64), nullable=False)
    descrip = db.Column(db.String(512), nullable=True)
    fun_type = db.Column(db.Integer(), nullable=False,comment="1:agent，2：系统函数，3：外部接口")
    price = db.Column(db.Integer(), nullable=False,default=0)
    interaction_mode = db.Column(db.String(1), nullable=False,comment="交互类型：I：输出需要传递给主智能体，B：Backend只在后台运行任务")
    inter_val_name = db.Column(db.String(64), nullable=True,comment="输出需要传递给主智能体的变量名")
    need_reconize = db.Column(db.Boolean, nullable=False,default=False,comment="是否需要识别")
    created_at = db.Column(db.DateTime, nullable=False,server_default=func.current_timestamp(),comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False,comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True,server_default=func.current_timestamp(),comment="更新时间")
    updated_by = db.Column(StringUUID, nullable=True,comment="更新人")
    @property
    def type_zh_str(self)->str:
        return RobFuncType.get_zh_str(self.fun_type)
    
    @property
    def type_code(self)->str:
        return RobFuncType.get_code(self.fun_type)
    
    @property
    def terms(self)->list[IntentRecoTerms]:
        try:
            terms = db.session.query(IntentRecoTerms).filter(IntentRecoTerms.cmd_id==self.id).all()
        except Exception as e:
            logging.error(e)
            terms = []
        return terms
    
    def to_dict(self)->dict:
        return {"id":self.id,
                "name":self.name,
                "descrip":self.descrip,
                "type_code":self.type_code,
                }
    
    
class IntentRecGroup(db.Model):
    __tablename__ = "int_rec_groups"
    __table_args__ = (
        db.PrimaryKeyConstraint("id", name="int_rec_groups_pkey"),
    )
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),comment="如果是agent，则是系统agentID。")
    
    tenant_id =  db.Column(StringUUID, nullable=False,comment="租户ID")
    collection_name = db.Column(db.String(128), nullable=False,comment="集合名称")
    dataset_id = db.Column(StringUUID, nullable=False,comment="数据集ID")
    document_id = db.Column(StringUUID, nullable=False,comment="文档ID")
    name = db.Column(db.String(128), nullable=False,comment="名称")
    descrip = db.Column(db.String(512),nullable=True)
    doc_language = db.Column(db.String(32), nullable=True,comment="文档语言")
    created_at = db.Column(db.DateTime, nullable=False,server_default=func.current_timestamp(),comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False,comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True,server_default=func.current_timestamp(),comment="更新时间")
    updated_by = db.Column(StringUUID, nullable=True,comment="更新人")
    @property
    def cmds(self)->list[RobFuncs]:
        try:
            funcs = db.session.query(RobFuncs).join(IntentRecMap,IntentRecMap.cmd_id==RobFuncs.id).filter(IntentRecMap.group_id==self.id).all()
        except Exception as e:
            funcs = []
        return funcs

class IntentRecMap(db.Model):
    __tablename__ = "int_rec_group_cmd_map"
    __table_args__ = (
        db.PrimaryKeyConstraint('group_id','cmd_id',name='idx_int_rec_group_cmd_map_pk'),
        db.Index('idx_int_rec_group_cmd_map_group', 'group_id'),
    )
    group_id = db.Column(StringUUID, nullable=False,comment="分组id")
    cmd_id = db.Column(StringUUID, nullable=False,comment="指令id")
    tenant_id = db.Column(StringUUID, nullable=False,comment="租户id")
    created_at = db.Column(db.DateTime, nullable=False,server_default=func.current_timestamp())
    created_by = db.Column(StringUUID, nullable=False,comment="创建人")

